package pyip.lib.javalearn.classloader.load.rule;

import java.net.MalformedURLException;

/**
 * 1) contextClassLoader子线程会继承父线程的contextClassLoader
 * 2) 主线程，也就是执行main()方法的那个线程，默认的contextClassLoader是system classloader
 */
public class ContextClassLoaderDemo {

    public static Exception GLOBAL_EXCEPTION = null;

    // public static A GLOBAL_A = null;

    public static void main(String[] args) throws MalformedURLException, ClassNotFoundException {
        try {
            Object o = Class.forName("pyip.lib.javalearn.classloader.load.rule.A", false, new MyClassLoader()).newInstance();
            A a = (A) Class.forName("pyip.lib.javalearn.classloader.load.rule.A", false, new MyClassLoader()).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }

        System.out.println("MainClass getClassLoader --- " + ContextClassLoaderDemo.class.getClassLoader());
        System.out.println("MainClass getContextClassLoader --- " + Thread.currentThread().getContextClassLoader());
        Thread innerThread1 = new InnerThread21();
        innerThread1.start();
    }

}

class InnerThread21 extends Thread {
    @Override
    public void run() {
        System.out.println();

        MyClassLoader myClassLoader = new MyClassLoader();
        Thread.currentThread().setContextClassLoader(myClassLoader);
        System.out.println("InnerThread1 setContextClassLoader(myClassLoader)");
        System.out.println("InnerThread1 getContextClassLoader --- " + Thread.currentThread().getContextClassLoader());

        Thread innerThread2 = new InnerThread22();
        innerThread2.start();
    }
}

class InnerThread22 extends Thread {
    @SuppressWarnings("rawtypes")
    @Override
    public void run() {
        System.out.println();
        System.out.println("InnerThread2 getContextClassLoader --- " + Thread.currentThread().getContextClassLoader());
        try {
            // A a = (A) Class.forName("pyip.lib.javalearn.classloader.load.rule.A", false, Thread.currentThread().getContextClassLoader()).newInstance();
            // System.out.println("InnerThread2 new A, A.class.getClassLoader() --- " + A.class.getClassLoader());
            // a.doNothing();

            // 使用MyClassLoader加载A, A.newInstance报错, 需要添加修饰符到类 public class A 才能正常运行;(自定义类加载的机制中反射获取类对象时会有安全机制的限制，所以只能用public)
            // 使用SystemClassLoader加载A, 则没有这个问题.
            // java.lang.IllegalAccessException: Class pyip.lib.javalearn.classloader.load.rule.InnerThread22 can not access a member of class
            // pyip.lib.javalearn.classloader.load.rule.A with modifiers "public"
            Class clazzA = Class.forName("pyip.lib.javalearn.classloader.load.rule.A", false, Thread.currentThread().getContextClassLoader());
            System.out.println();
            System.out.println("--after load class by MyClassLoader");
            // Class<A> clazzA = (Class<A>) Class.forName("pyip.lib.javalearn.classloader.load.rule.A");
            System.out.println("InnerThread2 Class.forName, clazzA.getClassLoader() --- " + clazzA.getClassLoader());
            System.out.println("InnerThread2 Class.forName, A.class.getClassLoader() --- " + A.class.getClassLoader());
            System.out.println("clazzA == A.class --- " + (clazzA == A.class));
            A aa = (A) clazzA.newInstance();
            // ContextClassLoaderDemo.GLOBAL_A = (A) clazzA.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
            ContextClassLoaderDemo.GLOBAL_EXCEPTION = e;
        }

        B b = null;
        // b = new B();
        try {
            b = (B) Class.forName("pyip.lib.javalearn.classloader.load.rule.B").newInstance();
            System.out.println();
            System.out.println("--after load class by Class.forName null ClassLoader");
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("InnerThread2 b.getClass().getClassLoader() --- " + b.getClass().getClassLoader());

        System.out.println("java.lang.StringBuilder.class.getClassLoader " + java.lang.StringBuilder.class.getClassLoader());
    }
}
